/*
 * user_spi_driver.c
 *
 *  Created on: Jan 30, 2023
 *      Author: dk007
 */
#include "user_config.h"
#include "CH58x_common.h"
#include "sys_init.h"
#include "user_spi_driver.h"


static uint8_t volatile is_spi_init_flag = 0;
void nfc_spi_init(void) {
#ifdef NFC_USE_HW_SPI
    GPIOPinRemap(ENABLE, RB_PIN_SPI0);

    GPIO_ResetBits(SPIM0_SS_PORT, SPIM0_SS_PIN);
    GPIO_ModeCfg(SPIM0_SS_PORT, SPIM0_SS_PIN, GPIO_ModeOut_PP_5mA);
    GPIO_ModeCfg(SPIM0_SCK_PORT, SPIM0_SCK_PIN, GPIO_ModeOut_PP_5mA);
    GPIO_ModeCfg(SPIM0_MOSI_PORT, SPIM0_MOSI_PIN, GPIO_ModeOut_PP_5mA);

    SPI0_MasterDefInit();
    SPI0_CLKCfg(8);
    R8_SPI0_CTRL_CFG |= RB_SPI_MST_DLY_EN;
    SPI0_DataMode(Mode0_HighBitINFront);
#else
    if(is_spi_init_flag){
        return;
    }
    GPIO_ResetBits(SPIM1_SS_PORT, SPIM1_SS_PIN);
    GPIO_ModeCfg(SPIM1_SS_PORT, SPIM1_SS_PIN, GPIO_ModeOut_PP_5mA);
    GPIO_ModeCfg(SPIM1_SCK_PORT, SPIM1_SCK_PIN, GPIO_ModeOut_PP_5mA);
    GPIO_ModeCfg(SPIM1_MOSI_PORT, SPIM1_MOSI_PIN, GPIO_ModeOut_PP_5mA);
    GPIO_ModeCfg(SPIM1_MISO_PORT, SPIM1_MISO_PIN, GPIO_ModeIN_Floating);

  //  GPIO_SetBits(SPIM1_SCK_PORT, SPIM1_SCK_PIN);
  //  GPIO_SetBits(SPIM1_MOSI_PORT, SPIM1_MOSI_PIN);
#endif
    //需要拉高，不然会读写数据失败
    USER_NFC_SPI_NSS_H();

    is_spi_init_flag = 1;
}

#if(NFC_CHIP_TYPE != FM5114B_NFC)
void nfc_spi_uninit(void){
//    GPIO_ResetBits(SPIM1_SCK_PORT, SPIM1_SCK_PIN);
//    GPIO_ResetBits(SPIM1_MOSI_PORT, SPIM1_MOSI_PIN);
//    GPIO_ResetBits(SPIM1_MISO_PORT, SPIM1_MISO_PIN);
    if(!is_spi_init_flag){
        return;
    }
    GPIO_ModeCfg(SPIM0_SCK_PORT, SPIM0_SCK_PIN, GPIO_ModeIN_PD);
    GPIO_ModeCfg(SPIM0_MOSI_PORT, SPIM0_MOSI_PIN, GPIO_ModeIN_PD);
    GPIO_ModeCfg(SPIM0_MISO_PORT, SPIM0_MISO_PIN, GPIO_ModeIN_PD); //一定要配置为下拉模式

    is_spi_init_flag = 0;
}
#endif


void delay(uint32_t n)
{
    while (n--);
}

/*******************************************************************************
*函数名：  spi_nss_h
*功能：
*入口参数：
*返回参数：
*作者：    Frank
*******************************************************************************/
void spi_nss_h(void) {
     USER_NFC_SPI_NSS_H();
}

/*******************************************************************************
*函数名：  spi_nss_l
*功能：
*入口参数：
*返回参数：
*作者：    Frank
*******************************************************************************/
void spi_nss_l(void) {
     USER_NFC_SPI_NSS_L();
}

__HIGH_CODE
__attribute__((noinline))
static uint8_t SPIx_ReadWriteByte(uint8_t data) {

#ifdef NFC_USE_HW_SPI
    R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
    R8_SPI0_BUFFER = data; // 启动传输
    while(!(R8_SPI0_INT_FLAG & RB_SPI_FREE));
    return (R8_SPI0_BUFFER); //接收这里需要确认
#else
    uint8_t mark = 0x80;
    uint8_t i = 0;
    uint8_t temp_data = 0;

    for (i=0; i<8; i++) {
        if (data & mark) {
            SPIM1_MOSI_H();
        }else {
            SPIM1_MOSI_L();
        }
        SPIM1_SCK_H();
        temp_data <<= 1;
        temp_data |= SPIM1_MISO();
        mark >>= 1;
        SPIM1_SCK_L();
    }

    return temp_data;
#endif
}

/*******************************************************************************
*函数名：  spi_read_write
*功能：    SPI写入/读出数据
*入口参数：
*返回参数：
*作者：    Lochy.Huang
*******************************************************************************/
uint8_t spi_read_write(
                    uint8_t * pTxBuffer,
                    uint16_t wTxLength,
                    uint16_t wRxBufSize,
                    uint8_t * pRxBuffer,
                    uint16_t * pRxLength){
    uint16_t i = 0;
    uint8_t rx_temp;

//    static uint8_t test_cnt = 0;
//    if(test_cnt < 3){
//        dk_log_hex("tx", pTxBuffer, wTxLength);
//        test_cnt++;
//    }

    for (i=0; i<wTxLength; i++) {
        rx_temp = SPIx_ReadWriteByte(pTxBuffer[i]);
        if (pRxBuffer != NULL) {
            pRxBuffer[i] = rx_temp;
        }
    }
    *pRxLength = wTxLength;
    return wTxLength;
}

uint8_t spi_transceive(
                    uint8_t * pTxBuffer,
                    uint16_t wTxLength,
                    uint8_t * pRxBuffer,
                    uint16_t * pRxLength){
    uint16_t i = 0;
    uint8_t rx_temp;

    spi_nss_l();
    *pRxLength = wTxLength;
//    static uint8_t test_cnt = 0;
//    if(test_cnt < 3){
//        dk_log_hex("tx", pTxBuffer, wTxLength);
//        test_cnt++;
//    }

    for (i=0; i<wTxLength; i++) {
        rx_temp = SPIx_ReadWriteByte(pTxBuffer[i]);
        if (pRxBuffer != NULL) {
            pRxBuffer[i] = rx_temp;
        }
    }

    spi_nss_h();

    return 0;
}

uint8_t DEV_ReadSR(uint8_t sr)
{
    uint8_t byte = 0;
    spi_nss_l();    //使能器件

    SPIx_ReadWriteByte(sr);          //发送读取状态寄存器命令
    byte = SPIx_ReadWriteByte(0Xff);        //读取一个字节

    spi_nss_h();                           //取消片选
    return byte;
}

void DEV_WriteSR(uint8_t sr, uint8_t value)
{
    spi_nss_l();    //使能器件

    SPIx_ReadWriteByte(sr);                   //发送读取状态寄存器命令
    SPIx_ReadWriteByte(value);

    spi_nss_h();                            //取消片选
}
